﻿package CutLoad.cookies
{
	import CutLoad.*;
	import CutLoad.components.loadbar.Loadbar;
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Graphics;
	import flash.display.Loader;
	import flash.display.LoaderInfo;
	import flash.display.PixelSnapping;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.net.URLRequest;

	/**
	 * 加载图片,并缓存，亮点：1.如果已经加载过了，就会从缓存里拿到一份。2.如果前面已经有在加载了，这里会循环等待。
	 * @author smallerbird mail:smallerbird@gmail.com  site:www.mkigm.com QQ群:49983196
	 * 
	 */	
	public class CLoadImg extends Base
	{
		private var myLoad:Loader
		private var url:String="";
		//
		private var imgimg:Bitmap=null;
		//加载图片的长宽
		private var imgW:Number,imgH:Number;
		private var loadBarTxtColor:Number;
		private var isHasStart:Boolean=true;
		//
		private var myImg:Bitmap=null
		//还未加载完成时，预览方块
		private var spRect:Sprite=null;
		//加载
		private var  loadBar:Loadbar
		//加载的进度信息,总大小和已经加载的
		private var _bytesLoaded:Number=0;
		private var _bytesTotal:Number=0;
		//
		/**
		 * 加载一个图片，初始化，注：如果这里设置宽和高的话，加载出来的图片的宽和高会强制设为这个值，如果没有设置，图片会显示自己的宽高。
		 * @param strUrl
		 * @param w 宽
		 * @param h 高 
		 * @param funCompet 是完全获得图片后，外部要进行的函数  格式:function(me:CLoadImg):void
		 * @param loadBarTxtColor 进度指示文字色
		 * @param funError 错误回调方法
		 * @param isStart 是否开始加载默认是开始的true
		 * 
		 */		
		public function CLoadImg(strUrl:String,w:Number=0,h:Number=0,funCompet:Function=null,loadBarTxtColor:Number=0x000000,funError:Function=null,isStart:Boolean=true){
			this.url=strUrl;
			showRect(w,h)
			imgW=w
			imgH=h;
			this.loadBarTxtColor=loadBarTxtColor;
			if(funCompet==null) funCompet=function(me:CLoadImg):void{}
			this.funCompet=funCompet;
			if(funError==null) funError=function(me:CLoadImg):void{}
			this.funError=funError;
			//
			isHasStart=false;
			if(isStart) start();
			//
		}	
		/**
		 * 开始加载 
		 * 
		 */		
		public function start():Boolean{
			if(isHasStart) return false;
			isHasStart=true;
			var strUrl:String=this.url;
			var w:Number=this.imgW;
			var h:Number=this.imgH;
			if(IS_BUFFER){
				var objBuffer:Object=getBitmapForBuffer(strUrl);
				if(objBuffer!=null){
					bufferId=objBuffer.id;
					if(objBuffer.bd==null){
						//trace("等待.."+bufferId+" "+objBuffer.url);
						if(objBuffer.states==2){
							//不用等了，是没有找到
							this.funError(this);
						}else{
							this.addEventListener(Event.ENTER_FRAME,waiBufferLoad);
						}
					}else{
						//当加载到显示对象时，。。
						var img:Bitmap=newBitmap(CLoadImg.Buffer.getOne(this.bufferId).bd.clone());
						cmpdo(img);
						//trace("缓存:"+strUrl);
						//md 2012-1-10
						//this.addEventListener(Event.ADDED_TO_STAGE,cmpStage);
					}
				}else{
					//trace("加载:"+strUrl);
					//-----------------同下面代码一样
					loadBar=Loadbar.getOnlyTxtLoadBar(w,h,10,loadBarTxtColor)
					loadBar.setXY(0,0,this);
					loadBar.visible=_loadBarVisible
					//
					bufferId=CLoadImg.add({url:this.url,bd:null,states:0})
					myLoad=new Loader();
					myLoad.contentLoaderInfo.addEventListener(Event.COMPLETE,cmp);
					myLoad.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS,funProgress);
					myLoad.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,error);
					myLoad.load(new URLRequest(strUrl));
				}
			}else{
				//-----------------同上面代码一样
				//trace("直接加载,没有缓存:"+strUrl)
				loadBar=Loadbar.getOnlyTxtLoadBar(w,h,10,loadBarTxtColor)
				loadBar.setXY(0,0,this);
				loadBar.visible=_loadBarVisible
				//
				//bufferId=CLoadImg.add({url:this.url,bd:null,states:0})
				myLoad=new Loader();
				myLoad.contentLoaderInfo.addEventListener(Event.COMPLETE,cmp);
				myLoad.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS,funProgress);
				myLoad.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,error);
				myLoad.load(new URLRequest(strUrl));
			}
			return true;
		}
		private function funProgress(e:ProgressEvent):void{
			if(!_loadBarVisible){
				loadBar.visible=false;
				return;
			}
			var pre:Number=Math.floor((e.bytesLoaded/e.bytesTotal)*100)/100;
			_bytesLoaded=e.bytesLoaded;
			_bytesTotal=e.bytesTotal;
			if(isNaN(pre)) pre=1;
			loadBar.setValue(pre,"");
			loadBar.dreawing();
		}
		private var _loadBarVisible:Boolean=true;
		/**
		 * 显否显示加载进度条 
		 * @return 
		 * 
		 */		
		public function get loadBarVisible():Boolean{
			return _loadBarVisible;
		}
		/**
		 * 是否不显示进度条 
		 * @param isShowShow
		 * 
		 */		
		public function set loadBarVisible(isShowShow:Boolean):void{
			_loadBarVisible=isShowShow;
			if(loadBar!=null) loadBar.visible=isShowShow;
		}
		/**
		 * 返回当前加载图片路径 
		 * @return 
		 * 
		 */		
		public function get imgPath():String{
			return this.url
		}
		/**
		 * 获得已加载的字节数 
		 * @return 
		 * 
		 */		
		public function get bytesLoaded():Number{
			return _bytesLoaded;
		}
		/**
		 * 获得文件的总字节数 
		 * @return 
		 * 
		 */
		public function get bytesTotal():Number{
			return this._bytesTotal;
		}
		/**
		 * 返回百分比 
		 * @param type 黙认为xx%  当为1里 xx.xx%
		 * @return 
		 * 
		 */		
		public function getLoadProgressPercen(type:Number=1):Number{
			var num:Number=bytesLoaded/bytesTotal;
			if(type==1){
				return Math.floor(num*100);
			}else{
				return Math.floor(num*10000)/100;
			}
		}
		/**
		 * 是否开启缓存，默认是开启的 
		 */		
		public static var IS_BUFFER:Boolean=true;
		//
		/**
		 * 存储缓存，单个元素格式：｛url:图片地址,bd:BitmapData对象｝
		 */		
		public static var Buffer:CArray=new CArray();
		/**
		 * 从缓存中返回一个 缓冲对象｛url:图片地址,bd:BitmapData对象｝
		 * @param urlSearch 图片地址,注：如果有缓存数组的下标话，这一项设为:""  设置参数index
		 * @param index  缓存数组的下标
		 * @return 
		 * 
		 */		
		public static function getBitmapForBuffer(urlSearch:String="",index:Number=-1):Object{
			var obj:Object
			if(urlSearch==""){
				if(index<0||index>Buffer.length) throw new Error("");
				obj=Buffer.getOne(index);
				return obj;
			}else{
				for(var i:Number=0;i<Buffer.length;i++){
					obj=Buffer.getOne(i);
					if(obj.url==urlSearch){
						return obj;
					}
				}
				return null;
			}
		}
		//
		private var bufferId:Number=0;
		//完全获得图片后，外部要进行的函数。
		private var funCompet:Function
		private var funError:Function;
		/**
		 *返回加载图片的 长宽
		 * @return 对象格式：{w:宽,h:高}
		 * 
		 */		
		public function getLoadImgWH():Object{
			return {w:this.imgW,h:this.imgH}
		}
		/**
		 * 设置“图片没有加载完成时，显示的方块”色和透明度
		 * @param color 色
		 * @param a 透明度
		 * 
		 */		
		public function setShowRectColor(color:Number,a:Number=1):void{
			showRect_color=color;
			showRect_alpha=a;
			showRect(imgW,imgH);
		}
		private var showRect_color:Number=0xcccccc;
		private var showRect_alpha:Number=0;
		/**
		 * 设置背景颜色 
		 * @param bakcolor
		 * @param bakAlpha
		 * 
		 */		
		public function setBakColor(bakcolor:Number,bakAlpha:Number):void{
			this.showRect_color=bakcolor;
			this.showRect_alpha=bakAlpha;
		}
		//图片没有加载完成时，显示的方块
		private function showRect(w:Number,h:Number):void{
			if(w==0||h==0) return; 
			if(spRect==null){
				spRect=new Sprite();
				this.addChild(spRect);
			}
			var gg:Graphics=spRect.graphics;
			gg.clear();
			gg.beginFill(showRect_color,showRect_alpha);
			gg.drawRect(0,0,w,h);
			gg.endFill();
		}
		//精除方块
		private function clearRect():void{
			if(spRect!=null){
				this.removeChild(spRect);
				spRect=null;
			}
		}
		//
		protected function cmp(e:Event):void{
			loadBar.killMe();
			//
			var a:BitmapDataTool
			//var db:BitmapData=new BitmapData(myLoad.width,myLoad.height);
			//db.draw(myLoad);
			var db:BitmapData=BitmapDataTool.getAlphaImg(myLoad);
			myImg=newBitmap(db);
			//如果加载完
			if(IS_BUFFER){
				var objBuffer:Object=CLoadImg.Buffer.getOne(bufferId);
				objBuffer.states=1;
				objBuffer.bd=db.clone()
				//打印
				//printBufferList();
			}
			//
			cmpdo(myImg);
			//
			myLoad.contentLoaderInfo.removeEventListener(Event.COMPLETE,cmp);
		}
		protected function error(e:Event):void{
			loadBar.killMe();
			if(IS_BUFFER){
				var objBuffer:Object=getBitmapForBuffer(this.imgPath);
				if(objBuffer!=null) objBuffer.states=2;
			}
			this.funError(this);
		}
		private function cmpStage(e:Event):void{
			if(!IS_BUFFER){
				return;
			}
			var img:Bitmap=newBitmap(CLoadImg.Buffer.getOne(this.bufferId).bd.clone());
			cmpdo(img);
			this.removeEventListener(Event.ADDED_TO_STAGE,cmpStage);
		}
		private function newBitmap(bim:BitmapData):Bitmap{
			return new Bitmap(bim);
		}
		protected function cmpdo(img:Bitmap):void{
			myImg=img;
			this.clearRect();
			this.imgimg=img;
			if(imgW==0){
				imgW=img.width;
			}else{
				img.width=imgW
			}
			if(imgH==0){
				imgH=img.height;
			}else{
				img.height=imgH
			}
			img.x=img.y=0
			//trace(imgW,imgH);
			this.addChild(img);		
			//
			try{
				funCompet(this);
			}catch(e:ArgumentError){
				funCompet();
			}
		}
		public function get bitmapData():BitmapData{
			if(myImg==null) return null;
			return myImg.bitmapData.clone();
		}
		/**
		 * 获得它里面的图像的 bitmapData,并转换成一个简单的Bitmap,然后包装成Base
		 * @return 
		 * 
		 */		
		public function getBitmapDataToBase():Base{
			if(myImg==null) return null;
			return Base.getBase(new Bitmap(myImg.bitmapData.clone()));
		}
		//用于缓存功能--------------------------------------------start-------------------------
		/**
		 *添加一个缓存 
		 * @param o
		 * @return 
		 * 
		 */
		public static function add(o:Object):Number{
			var indexTem:Number=CLoadImg.Buffer.add(o);
			o.id=indexTem
			return indexTem;
		}
		/**
		 * 打印出缓存列表
		 * 
		 */		
		public static function printBufferList():void{
			trace(CLoadImg.Buffer);
		}
		//等待缓存加载图
		private function waiBufferLoad(e:Event):void{
			var objBuffer:Object=CLoadImg.Buffer.getOne(bufferId);
			if(objBuffer==null) return;
			if(objBuffer.bd!=null){
				var img:Bitmap=newBitmap(objBuffer.bd.clone());
				cmpdo(img);
				//trace("找到了,缓存!")
				this.removeEventListener(Event.ENTER_FRAME,waiBufferLoad);
			}else{
				if(objBuffer.states==2){
					//不用等了，是没有找到
					this.funError(this);
				}
				//trace("等待.."+bufferId)
			}
		}
		//用于缓存功能--------------------------------------------end---------------------------
		//覆盖
		override public function killMe():void{
			//如果还在加载，就取消它
			if(myLoad!=null){
				if(myLoad.contentLoaderInfo.hasEventListener(Event.COMPLETE)){
					myLoad.contentLoaderInfo.removeEventListener(Event.COMPLETE,cmp);
				}
			}
			//如果还在等待加载
			if(this.hasEventListener(Event.ENTER_FRAME)){
				this.removeEventListener(Event.ENTER_FRAME,waiBufferLoad);
			}
			//
			if(this.hasEventListener(Event.ADDED_TO_STAGE)){
				this.removeEventListener(Event.ADDED_TO_STAGE,cmpStage);
			}
			//
			super.killMe();
		}
		override public function setWH(w:Number=0, h:Number=0):void{
			if(imgimg!=null){
				this.imgimg.width=w;
				this.imgimg.height=h;
			}
			imgW=w;
			imgH=h;
		}
		override public function getShowWidth():Number{
			return imgW
		}
		override public function getShowHeight():Number{
			return imgH
		}
	}
}